package com.feib.soeasy.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.feib.soeasy.model.Group;
import com.feib.soeasy.model.LabelValue;
import com.feib.soeasy.model.Payment;
import com.feib.soeasy.model.PaymentCanceledReason;
import com.feib.soeasy.model.WriteOffPayment;
import com.feib.soeasy.pagination.PaginatedList;
import com.feib.soeasy.service.GroupService;
import com.feib.soeasy.service.PaymentCanceledReasonService;
import com.feib.soeasy.service.PaymentService;
import com.feib.soeasy.util.UserUtil;


import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontBind;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.DateTypeConverter;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.ValidationErrorHandler;
import net.sourceforge.stripes.validation.ValidationErrors;

/**
 * @title (#)Soez2003ActionBean.java <br>
 * @description 帳單人工銷帳作業 Controller<br>
 * @author Leo Lee
 * @version 1.0.0 2010/11/27
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/11/27 create by Leo Lee<br>
 */
public class Soez1017ActionBean extends BaseActionBean implements ValidationErrorHandler {

    /**
     * 帳單人工銷帳作業畫面
     */
    private static final String DEFAULT_JSP = "/WEB-INF/views/soez1017/soez1017.jsp";

    /**
     * 帳單整批上傳放行清單畫面
     */
    private static final String PAYMENT_LIST_JSP = "/WEB-INF/views/soez1017/soez1017List.jsp";
    
    /**
     * 檔案內容
     */
    private static final String AJAX_QUERY_PAYMENT_JSP = "/WEB-INF/views/soez1017/paymentList.jsp";
    
    /**
     * 業者代號查詢畫面
     */
    private static final String AJAX_QUERY_GROUP_JSP = "/WEB-INF/views/soez1017/groupPopUpList.jsp";
    
    /**
     * 註銷處理結果畫面
     */
    private static final String AJAX_PAYMENT_CANCEL_JSP = "/WEB-INF/views/soez1017/paymentWriteoffResult.jsp";

    /**
     * 帳單放行結果畫面
     */
    private static final String AFTER_CONFIRM_JSP = "/WEB-INF/views/soez1017/afterConfirm.jsp";
    
    /**
     * 查詢條件
     */
    @ValidateNestedProperties({
        @Validate(field="uploadFilePk", required=true, on={"doAjaxQueryPayments"}  )
        , @Validate(field="uploadDate", converter=DateTypeConverter.class )
    })
    private Payment qryPayment;

    /**
     * 帳單業者查詢條件
     */
    private Group qryGroup;

    @ValidateNestedProperties({
        @Validate(field="groupNo", required=true, on={"doAjaxQuery"}  )
    })
    private Group group;
    
    /**
     * 查詢表單（用於儲存CheckBox選中情況）
     */
    private ArrayList<Payment> checkPayment;
    
    /** 
     * 查詢條件-上傳日期起
     */
    //@Validate( required=true, on={"doAjaxQuery"}, converter=DateTypeConverter.class)
    private Date qryPayDueFrom;

    /**
     * 查詢條件-上傳日期迄
     */
    //@Validate( required=true, on={"doAjaxQuery"}, converter=DateTypeConverter.class)
    private Date qryPayDueTo;

    /**
     * 查詢結果
     */
    private PaginatedList<Payment> queryResult;
    
    /**
     * 帳單業者查詢結果
     */
    private PaginatedList<Group> queryGroupResult;

    /**
     * 查詢單筆Payment
     */
    private Payment resultPayment;
    
    /**
     * 銷帳處理結果
     */
    private boolean writeoffed;

    /**
     * 賬單放行結果
     */
    private String confirmMessage;

    /**
     * 檔案帳單明細查詢結果
     */
    private PaginatedList<Payment> queryPaymentResult;
    
    /**
     * 註銷原因選擇
     */
    private String paymentWriteOffCode;
    
    /**
     * 註銷原因說明
     */
    private String paymentWriteOffReason;
    
    @SpringBean("groupService")
    private GroupService groupService;

    @SpringBean("paymentService")
    private PaymentService paymentService;

    @SpringBean("paymentCanceledReasonService")
    private PaymentCanceledReasonService paymentCanceledReasonService;

    @DontBind
    @DefaultHandler
    public Resolution doDefault()
    {
        logger.debug("Enter doDefault mehtod.");
        return new ForwardResolution(DEFAULT_JSP); 
    }

    /**
     * 查詢
     * @return
     */
    public Resolution doAjaxQuery()
    {
        logger.debug("Enter doAjaxQuery mehtod.");
        try {
            //USER未輸入查詢條件，所以查詢物件會是NULL(查詢物件不可為NULL)
            if (null == qryPayment)
                qryPayment = new Payment();
            
            /* 如果不是銀行端，則查詢條件要加入帳單業者限制 */
            if (!UserUtil.isBankGroup())
            {
                Group group = new Group();
                group.setGroupPk(UserUtil.getUserGroup().getGroupPk());
                qryPayment.setGroup(group);
            }
            else if (null != group)
                qryPayment.setGroup(group);
            
            qryPayment.setPaymentStatus(new Integer(2));
            WriteOffPayment writeOffPayment = new WriteOffPayment();
            qryPayment.setWriteOffPayment(writeOffPayment);
            //呼叫服務查詢
            queryResult = paymentService.queryByPayment(qryPayment, qryPayDueFrom, qryPayDueTo, queryResult) ;

        }
        catch (Exception e) {
            logger.error("帳單人工銷帳作業查詢錯誤(Soez1017ActionBean.doAjaxQuery):", e);

            // 轉換錯誤訊息
            ValidationErrors errors = new ValidationErrors();
            errors.addGlobalError(new LocalizableError("doAjaxQuery.exception") );
            getContext().setValidationErrors(errors);
            // 回傳 錯誤 HTML fragments
            return super.errorsToHtmlStreams(errors);
        }

        return new ForwardResolution(PAYMENT_LIST_JSP);
    }

    /**
     * 帳單業者查詢
     * @return
     */
    public Resolution doAjaxQueryGroups()
    {
    	/* 進入賬單業者查詢,記錄LOG */
        logger.debug("Enter doAjaxQueryGroups mehtod.");
        try {
            /* 如果不是銀行端，則查詢條件要加入帳單業者限制 */
            if (!UserUtil.isBankGroup())
            {
                throw new Exception("No Authority");
            }


            /* USER未輸入查詢條件，所以查詢物件會是NULL(查詢物件不可為NULL) */
            if (null == qryGroup)
                qryGroup = new Group();

            /* 呼叫服務查詢 */
            queryGroupResult = groupService.queryByGroupExcludeBank(qryGroup, queryGroupResult);
        }
        /* 異常處理 */
        catch (Exception e) {
            logger.error("帳單上傳記錄查詢-帳單業者查詢錯誤(Soez9004ActionBean.doAjaxQueryGroups):", e);

            /* 轉換錯誤訊息 */
            ValidationErrors errors = new ValidationErrors();
            errors.addGlobalError(new LocalizableError("doAjaxQuery.exception") );
            getContext().setValidationErrors(errors);
            /* 回傳 錯誤 HTML fragments */
            return super.errorsToHtmlStreams(errors);
        }

        return new ForwardResolution(AJAX_QUERY_GROUP_JSP);
    }
    
    /**
     * 查詢轉入的帳單資料
     * @return
     */
    public Resolution doAjaxQueryFilePayments()
    {
        logger.debug("Enter doAjaxQueryFilePayments mehtod.");
        try {

            //呼叫服務查詢
            resultPayment = 
                paymentService.getPaymentByPk(qryPayment);
        }
        catch (Exception e) {
            logger.error("上傳記錄查詢-帳單內容查詢錯誤(Soez1017ActionBean.doAjaxQueryFilePayments):", e);

            // 轉換錯誤訊息
            ValidationErrors errors = new ValidationErrors();
            errors.addGlobalError(new LocalizableError("doAjaxQuery.exception") );
            getContext().setValidationErrors(errors);
            // 回傳 錯誤 HTML fragments
            return super.errorsToHtmlStreams(errors);
        }

        return new ForwardResolution(AJAX_QUERY_PAYMENT_JSP);
    }

    public Resolution doWriteOffPaymentsAction()
    {
        logger.debug("Enter doWriteOffPaymentsAction mehtod.");
        try {
            writeoffed = false;
            paymentService.doWriteOffPayments(qryPayment);
            writeoffed = true;
        }
        catch (Exception e) {
            logger.error("上傳記錄查詢-帳單內容查詢錯誤(Soez1017ActionBean.doAjaxQueryFilePayments):", e);

            // 轉換錯誤訊息
            ValidationErrors errors = new ValidationErrors();
            errors.addGlobalError(new LocalizableError("doAjaxQuery.exception") );
            getContext().setValidationErrors(errors);
            // 回傳 錯誤 HTML fragments
            return super.errorsToHtmlStreams(errors);
        }

        return new ForwardResolution(AJAX_PAYMENT_CANCEL_JSP);
    }
    
    /**
     * 賬單核銷
     * @return
     */
    public Resolution doAjaxPaymentWriteOff(){
    	/* 記錄LOG進入賬單核銷方法 */
        logger.debug("Enter doAjaxPaymentWriteOff mehtod.");
        try {
        	/* 檢查從Web頁面獲取的複選框狀態. */
        	if(checkPayment != null && checkPayment.size() > 0){ 
        		/* 處理頁面獲取的CheckBox,去掉其中的NULL */
        		ArrayList<Payment> tempCheckPayment = new ArrayList<Payment>();
        		for(int i = 0 ; i < checkPayment.size() ; i++){
        			if(checkPayment.get(i) != null){
        				tempCheckPayment.add(checkPayment.get(i));
        			}
        		}
        		/* 把處理過的資料集賦值給checkPayment */
        		checkPayment = tempCheckPayment;
        		
        		/* 批量核銷 */
        		paymentService.doWriteOffPayments(checkPayment, paymentWriteOffReason, paymentWriteOffCode);
        		/* 處理過後,如果資料集不為空則進入註銷環節(資料不可能為空,雖然頁面有Jquery卡住驗證,後台仍需進行判斷) */
        		if(checkPayment.size() > 0){
        			/* 修改注销代码標記，使之不能更改及删除.(系統內定的999(其他),不需要進行此操作) */
	        		if(!"999".equals(paymentWriteOffCode)){
	        			Group tempGroup = new Group();
	        			/* 當為銀行端時,從頁面獲取賬單業者相關信息 */
		        		if(group != null && group.getGroupNo() != null && UserUtil.isBankGroup()){
		        			/* 當為銀行端時,從頁面獲取賬單業者相關信息 */
		        			tempGroup = this.groupService.findByExactGroupNo(this.group.getGroupNo());
		        		}
		        		/* 當為賬單業者登入時,直接獲取登錄者的所屬賬單業者的相關信息 */
		        		else if(!UserUtil.isBankGroup()){
		        			tempGroup = UserUtil.getUserGroup();
		        		}
		        		/* 取得賬單業者的Pk */
	        			Long tempGroupPk = tempGroup.getGroupPk();
	        			
	        			PaymentCanceledReason paymentCanceledReasonInDb = new PaymentCanceledReason();
	        			/* 查询此次核銷代碼的資料 */
	        			paymentCanceledReasonInDb = this.paymentCanceledReasonService.queryByGroupPkAndCancelCode(tempGroupPk, paymentWriteOffCode);
	        			/* 檢查是否已經使用,如果未使用則修改其使用標記 */
	        			if(!"Y".equals(paymentCanceledReasonInDb.getIsUsed())){
	        				/* 设置已使用標記 */
		        			paymentCanceledReasonInDb.setIsUsed("Y");     
		        			/* 保存 */
			                this.paymentCanceledReasonService.save(paymentCanceledReasonInDb);
	        			}
	        		}
	        		/* 銷帳成功提示信息 */
	        		confirmMessage = "銷帳成功！";
        		}
        		/* 如果處理使用者選擇資料後,資料集大小為0,給出相應提示信息 */
        		else{
        			confirmMessage = "至少請選擇一筆!";
        		}
        	}
        	/* 從頁面獲取使用者選擇資料集失敗,並給出提示信息. */
        	else{
        		confirmMessage = "從頁面獲取使用者選則失敗,請聯繫系統管理員!";
        	}
        }
        /* 異常的處理及相應LOG的記錄 */
        catch (Exception e) {
            logger.error("帳單銷帳作業錯誤(Soez1017ActionBean.doAjaxPaymentWriteOff):", e);
            confirmMessage = "處理失敗！";
        }

        return new ForwardResolution(AFTER_CONFIRM_JSP);    	
    }
    
    /**
	 * @return selectedGroup
	 */
	public List<LabelValue> getSelectedPaymentWriteOffCode() {
		/* 新建Label,用來保存註銷代碼及註銷原因 */
		List<LabelValue> selectedPaymentCanceledCode = new ArrayList<LabelValue>();   
        /* 新建 註銷代碼 結果集,用戶保存從資料庫查詢結果 */
    	List<PaymentCanceledReason> tempPaymentCanceledCode;
    	/* 去數據庫查詢資料 */
    	try {
    		Group tempGroup = new Group();
    		/* 當為銀行端時,從頁面獲取賬單業者相關信息GroupNo */
    		if(this.group != null && this.group.getGroupNo() != null && UserUtil.isBankGroup()){	 
    			/* 根據GroupNo查詢賬單業者詳細信息 */
    			tempGroup = this.groupService.findByExactGroupNo(this.group.getGroupNo());
    		}
    		/* 當為賬單業者登錄時,獲取登錄者所屬的賬單業者信息 */
    		else if(!UserUtil.isBankGroup()){
    			tempGroup = UserUtil.getUserGroup();
    		}
    		/* 根據賬單業者的Pk查詢其已設定的銷帳代碼及銷帳原因 */
    		tempPaymentCanceledCode = this.paymentCanceledReasonService.queryAllReasonByGroupPk(tempGroup.getGroupPk());
    		/* 當有查詢到銷帳代碼設定相關資料時,轉化資料為可用數據 */
	    	if(null != tempPaymentCanceledCode && tempPaymentCanceledCode.size() > 0){
	    		LabelValue labelValue;
	    		/* 循環查詢結果,取出資料放入LabelValue中 */
	    		for(int i = 0 ; i < tempPaymentCanceledCode.size() ; i++){
	    			labelValue = new LabelValue();
	    			/* 顯示的賦值 */
	    			labelValue.setLabel(tempPaymentCanceledCode.get(i).getCanceledNo() + " " + tempPaymentCanceledCode.get(i).getCancelReason());
	    			labelValue.setValue(tempPaymentCanceledCode.get(i).getCanceledNo());
	    			/* 加入 LabelValue結果集中 */
	    			selectedPaymentCanceledCode.add(labelValue);
	        		}
	        	}
		}
    	/* 異常處理及記錄Log信息 */
    	catch (Exception e) {
			logger.error("獲取銷帳代碼失敗:" + e);
		}	    	
        
		return selectedPaymentCanceledCode;
	}
    
    public PaginatedList<Payment> getQueryResult() {
        return queryResult;
    }

    public void setQueryResult(PaginatedList<Payment> queryResult) {
        this.queryResult = queryResult;
    }
    
    public Payment getResultPayment() {
        return resultPayment;
    }

    public void setResultPayment(Payment resultPayment) {
        this.resultPayment = resultPayment;
    }

    
    /**
     * @return the writeoffed
     */
    public boolean isWriteoffed() {
        return writeoffed;
    }

    
    /**
     * @param writeoffed the writeoffed to set
     */
    public void setWriteoffed(boolean writeoffed) {
        this.writeoffed = writeoffed;
    }


    public PaginatedList<Payment> getQueryPaymentResult() {
        return queryPaymentResult;
    }



    public void setQueryPaymentResult(PaginatedList<Payment> queryPaymentResult) {
        this.queryPaymentResult = queryPaymentResult;
    }


    public Payment getQryPayment() {
        return qryPayment;
    }



    public void setQryPayment(Payment qryPayment) {
        this.qryPayment = qryPayment;
    }



    public Date getQryPayDueFrom() {
        return qryPayDueFrom;
    }



    public void setQryPayDueFrom(Date qryPayDueFrom) {
        this.qryPayDueFrom = qryPayDueFrom;
    }



    public Date getQryPayDueTo() {
        return qryPayDueTo;
    }



    public void setQryPayDueTo(Date qryPayDueTo) {
        this.qryPayDueTo = qryPayDueTo;
    }

	/**
	 * @return the checkPayment
	 */
	public ArrayList<Payment> getCheckPayment() {
		return checkPayment;
	}

	/**
	 * @param checkPayment the checkPayment to set
	 */
	public void setCheckPayment(ArrayList<Payment> checkPayment) {
		this.checkPayment = checkPayment;
	}

	/**
	 * @return the paymentWriteOffCode
	 */
	public String getPaymentWriteOffCode() {
		return paymentWriteOffCode;
	}

	/**
	 * @param paymentWriteOffCode the paymentWriteOffCode to set
	 */
	public void setPaymentWriteOffCode(String paymentWriteOffCode) {
		this.paymentWriteOffCode = paymentWriteOffCode;
	}

	/**
	 * @return the paymentWriteOffReason
	 */
	public String getPaymentWriteOffReason() {
		return paymentWriteOffReason;
	}

	/**
	 * @param paymentWriteOffReason the paymentWriteOffReason to set
	 */
	public void setPaymentWriteOffReason(String paymentWriteOffReason) {
		this.paymentWriteOffReason = paymentWriteOffReason;
	}

	/**
	 * @return the confirmMessage
	 */
	public String getConfirmMessage() {
		return confirmMessage;
	}

	/**
	 * @param confirmMessage the confirmMessage to set
	 */
	public void setConfirmMessage(String confirmMessage) {
		this.confirmMessage = confirmMessage;
	}

	/**
	 * @return the qryGroup
	 */
	public Group getQryGroup() {
		return qryGroup;
	}

	/**
	 * @param qryGroup the qryGroup to set
	 */
	public void setQryGroup(Group qryGroup) {
		this.qryGroup = qryGroup;
	}

	/**
	 * @return the group
	 */
	public Group getGroup() {
		return group;
	}

	/**
	 * @param group the group to set
	 */
	public void setGroup(Group group) {
		this.group = group;
	}

	/**
	 * @return the queryGroupResult
	 */
	public PaginatedList<Group> getQueryGroupResult() {
		return queryGroupResult;
	}

	/**
	 * @param queryGroupResult the queryGroupResult to set
	 */
	public void setQueryGroupResult(PaginatedList<Group> queryGroupResult) {
		this.queryGroupResult = queryGroupResult;
	}

	
}
